java8——lambed表达式

行为参数化的3中方式(策略模式)

  1. 匿名类
  2. lamada

函数式接口

函数式接口就是只定义一个抽象方法的接口。

Lambda表达式允许你直接内联,为函数式接口的抽象方法提供实现,并且将整个表达式座位函数式接口的一个实例。

java.util.function包中引入了的函数式接口

  1. Predicate
Interface Predicate<T>

Type Parameters:
T - the type of the input to the predicate

Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

抽象方法:

boolean test(T t)
Evaluates this predicate on the given argument.

Predicate<T>接口定义了一个名叫test的抽象方法,接收泛型T对象,返回一个boolean。

public class Main {

    public static void main(String[] args) {
        Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
        filter(listOfString, nonEmptyStringPredicate);
    }

    public static <T> List<T> filter(List<T> list, Predicate<T> p){
        List<T> results = new ArrayList<T>();
        for(T s : list){
            if(p.test(s)){
                results.add(s);
            }
        }
        return results;
    }
}
  1. Consumer
Interface Consumer<T>

Type Parameters:
T - the type of the input to the operation

All Known Subinterfaces:
Stream.Builder<T>

Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

抽象方法

void    accept(T t)
Performs this operation on the given argument.

Consumer<T>定义了一个名叫accept的抽象方法,它接受泛型T对象,没有返回(void)。如果需要访问类型T的对象,并对其执行某些操作,就可以使用这个接口。

  public static <T> void forEach(List<T> list,Consumer<T> consumer){
        for(T i:list){
            consumer.accept(i);
        }
    }
    
   forEach(Arrays.asList(1,2,3,4,5),(Integer i) -> System.out.println(i));
  1. Interface Function<T,R>
Type Parameters:
T - the type of the input to the function
R - the type of the result of the function

All Known Subinterfaces:
UnaryOperator<T>

Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

抽象方法:

R   apply(T t)
Applies this function to the given argument.

Function<T,R>接口定义了一个叫做apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象。如果要定义一个lambda,将输入对象的信息映射到输出,就可以使用这个接口。

  public static <T,R> List<R> map(List<T> list, Function<T,R> f){
            List<R> result = new ArrayList<>();
            for(T s:list){
                result.add(f.apply(s));
            }
            return  result;
    }
    
 List<Integer> l = map(Arrays.asList("lambdas","in","action"),(String s)->s.length());
    }

异常,lambda,还有函数式接口

任何函数式接口都不允许抛出受检异常(checked exception).如果需要Lambda表达式来抛出异常,有两种办法:

  1. 定义字一个自己的函数式接口,并声明受检异常。
  2. 把lambda包在一个try/catch中。
@FunctionalInterface
public interface BufferedReaderProcessor{
    String process(BufferdReader b) throws IOException
}
Function<BufferedReader,String> f = (BufferedReader b) ->{
    try{
        return b.readLine();
    }catch(IOException e){
        throw new RuntimeException(e);
    }
}

Lambda表达式使用局部变量

lambda表达式不仅能用到主体里的函数。还允许使用自有变量(不是参数,而是在外层作用域中定义的变量),就像匿名类一样。他们被称作捕获Lambda

int portNumber = 1337;
Runable r = () -> System.out.println(portNumber);

但是,Lambda可以没有限制的捕获(也就是在其主题中引用)实例变量和静态变量。但是局部变量必须显示的声明为final。

闭包

Lambda和匿名类可以做类似于闭包的事情:他们可以作为参数传递给方法,并且可以访问其作用域之外的变量。但是有一个显示:他们不能修改定义Lambda的方法的局部变量的内容。

方法引用

先前

inventory.sort((Apple a1,Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

之后(使用方法引用后java.util.Comparator.compareing):

inventory.sort(comparing(Apple::getWeight))

如何构建方法引用:方法引用主要有3类

  1. 指向静态方法的方法引用(例如Integer的parseInt方法)写作Integer::parseInt
  2. 指向任意类型实例方法的方法引用(例如String的length方法,写作String::length)
  3. 指向现有对象的实例方法的方法引用(假设你有一个局部变量expensiveTransaction用于存放Transaaction类型的对象,他支持实例方法getValue,那么你就可以写expensiveTransaction::getValue)。


    image

构造函数引用

对于一个现有的构造函数,可以利用它的名称和关键字new来创建它的一个引用:ClassName::new。它的功能与指向静态方法的引用类似。列入,假设有一个构造函数没有参数。它适合Supplier的签名()->Apple。

Suppier<Apple> c1 = Apple::new;
Apple a1 = c1.get();

这就等价于:

Supplier<Apple> c1 = () -> new Apple();
Apple a1 = c1.get();

如果构造函数的签名是Apple(Integer weight),那么它就适合Function接口的签名,于是你可以这样写:

Function<Integer,Apple> c2 = Apple::new;
Apple a2 = c2.apply(110);

等价于:

Function<Integer,Apple> c2 = (weight) ->new Apple(weight);
Apple a2 = c2.apply(110);

谓词复合

谓词接口包括三个方法:negate,and和or,让你可以重用已有的Predicatre来创建更复杂的谓词。


image

函数复合

image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容

  • 简介 概念 Lambda 表达式可以理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主...
    刘涤生阅读 3,166评论 5 18
  • lambda表达式(又被成为“闭包”或“匿名方法”)方法引用和构造方法引用扩展的目标类型和类型推导接口中的默认方法...
    183207efd207阅读 1,422评论 0 5
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,062评论 9 118
  • Java8 in action 没有共享的可变数据,将方法和函数即代码传递给其他方法的能力就是我们平常所说的函数式...
    铁牛很铁阅读 1,146评论 1 2
  • 声明:本文翻译自The Java™ Tutorials(官方文档) 简述 匿名类有一个问题,如果匿名类的实现非常简...
    猴子小皮球阅读 4,542评论 0 9